<template>
  <div ref="canvas"></div>
</template>

<script lang="ts" setup>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { GUI } from "three/examples/jsm/libs/lil-gui.module.min.js"
import { ref, onMounted } from "vue";

// 画布
const canvas = ref<any>('');
// 场景
const scene = new THREE.Scene();
// 光源
const ambientLight = new THREE.AmbientLight(0xffffff, 1);
scene.add(ambientLight);

// 材质
const material = new THREE.MeshLambertMaterial({
  color: 0x00ffff, // 颜色
  side: THREE.DoubleSide, // 双面可见
});
// 几何体
const geometry = new THREE.BoxGeometry(50, 50, 50);
// 网格模型 - Mesh
const mesh = new THREE.Mesh(geometry, material);

const mesh2 = new THREE.Mesh(geometry.clone(), material/* material.clone() */);
mesh2.material.color = new THREE.Color(0x00f0f0);
mesh2.translateX(100);

// 设置不可见 - 控制是否隐藏该材质对应的模型对象 如果多个模型引用了同一个材质，如果该材质.visible设置为false，意味着隐藏绑定该材质的所有模型
// material.visible = false;

// 分组
const group = new THREE.Group();
// 将网格模型Mesh加入到分组中
group.add(mesh, mesh2);
// 将分组加入到场景中 - 所以现在就是: 场景下属group，ambientLight，group下属mesh，mesh2
scene.add(group);

// 相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 3000);
camera.position.set(200, 200, 200);
camera.lookAt(0, 0, 0);
// 渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);

const guiObj = {
  translate: false, // 是否平移
  scale: false, // 是否缩放
  rotate: false, // 是否旋转
}
// 可视化操作界面
const gui = new GUI();
// @ts-ignore
gui.add(guiObj, 'translate').name('是否沿Y轴平移');
// @ts-ignore
gui.add(guiObj, 'scale').name('是否缩放');
// @ts-ignore
gui.add(guiObj, 'rotate').name('是否沿Y轴旋转');
// 渲染函数
function render() {
  if (guiObj.translate && group.position.y < window.innerHeight) {
    // 沿着Y轴平移mesh1和mesh2的父对象，mesh1和mesh2跟着平移
    group.translateY(10);
  }
  if (guiObj.scale) {
    // 父对象缩放，子对象跟着缩放
    group.scale.set(2,2,2);
  }
  if (guiObj.rotate) {
    // 父对象旋转，子对象跟着旋转
    group.rotation.y += 0.005;
  }

  renderer.render(scene, camera);
  requestAnimationFrame(render);
}
// 相机控件
const orbitControl = new OrbitControls(camera, renderer.domElement);
orbitControl.update();

onMounted(() => {
  canvas.value.appendChild(renderer.domElement);
  render();
});
</script>
